package com.seednia.module.core.user.service.ws;

import java.util.List;

import javax.ws.rs.DELETE;
import javax.ws.rs.FormParam;
import javax.ws.rs.GET;
import javax.ws.rs.POST;
import javax.ws.rs.PUT;
import javax.ws.rs.Path;
import javax.ws.rs.PathParam;
import javax.ws.rs.Produces;
import javax.ws.rs.QueryParam;
import javax.ws.rs.WebApplicationException;
import javax.ws.rs.core.MediaType;

import org.apache.commons.logging.Log;
import org.apache.commons.logging.LogFactory;

import com.seednia.foundation.framework.dto.QueryParams;
import com.seednia.foundation.framework.service.AbstractWebService;
import com.seednia.foundation.framework.service.RemoteException;
import com.seednia.foundation.framework.service.RequestContext;
import com.seednia.foundation.framework.service.ServiceContainer;
import com.seednia.foundation.framework.service.ServiceException;
import com.seednia.module.core.resource.dto.MediaDto;
import com.seednia.module.core.user.dto.UserCriteria;
import com.seednia.module.core.user.dto.UserDto;
import com.seednia.module.core.user.service.IUserService;

/**
 * User service exposing REST protocol
 * @author Young Suk Ahn
 *
 */
// @Path("/user/") //: http://localhost:8080/seednia-webapp/ws/UserServiceRest/users
@Produces("application/xml")
public class UserRestService extends AbstractWebService implements IUserWebService 
{
	
	private IUserService userService = null;
	
	private static final Log logger = LogFactory.getLog(UserRestService.class);

	public UserRestService() 
	{
	}

	public IUserService getUserService() {
		if (userService == null) {
			userService = (IUserService)ServiceContainer.getInstance().getByType(IUserService.class);
		}
		return userService;
	}

	public void setUserService(IUserService userService) {
		this.userService = userService;
	}
	

	@GET
    @Path("/{xid}")
    @Produces({MediaType.APPLICATION_JSON})		
	public UserDto getUser(@QueryParam("accessToken") String accessToken, @PathParam("xid") String xid) 
	{
		UserDto result = null;
		try {
			RequestContext requestContext = createRequestContext(accessToken);
			UserCriteria criteria = new UserCriteria();
			super.setCriteriaXid(criteria, xid);
			result = getUserService().getUser(requestContext, criteria);
		} catch (ServiceException e) {
			logger.error("Exception at UserRestService.getUser", e);
			throw new WebApplicationException(e);
		}
        return result;
    }
	
	@GET
    @Produces({MediaType.APPLICATION_JSON})
    public List<UserDto> getUserList(@QueryParam("accessToken") String accessToken, @QueryParam("criteria") UserCriteria criteria
    		, @QueryParam("params") QueryParams params) 
    {
		List<UserDto> result = null;
		try {
			params = super.obtainQueryParam(params);
			RequestContext requestContext = createRequestContext(accessToken);
			result = getUserService().getUserList(requestContext, criteria, params);
		} catch (ServiceException e) {
			logger.error("Exception at UserRestService.getUserList", e);
			throw new WebApplicationException(e);
		}
		
        return result;
    }
	
	@POST
	@Override
    public Long insertUser(@QueryParam("accessToken") String accessToken, @FormParam("record") UserDto record) 
	{
		Long retval = null;
		try {
			RequestContext requestContext = createRequestContext(accessToken);
			retval = getUserService().insertUser(requestContext, record);
		} catch (ServiceException e) {
			logger.error("Exception at UserRestService.insertUser", e);
			throw new WebApplicationException(e);
		}
		return retval;
    }
	
    @PUT
    @Override
    public int updateUser(@QueryParam("accessToken") String accessToken, @FormParam("record") UserDto record) {
		
    	int result = 0;
		try {
			RequestContext requestContext = createRequestContext(accessToken);
			result = getUserService().updateUser(requestContext, record);
		} catch (ServiceException e) {
			logger.error("Exception at UserRestService.updateUser", e);
			throw new WebApplicationException(e);
		}
		
        return result;
    }
	

	
	@DELETE
    @Produces({MediaType.APPLICATION_JSON})
	@Override
    public int deleteUser(@QueryParam("accessToken") String accessToken, @QueryParam("criteria") UserCriteria criteria) 
	{
		// Web Service can only delete unique
		if (!getUserService().returnsUnique(criteria)) {
			throw new WebApplicationException(new IllegalArgumentException("Crieria does not return unique result"));
		}
		int result = 0;
		try {
			RequestContext requestContext = createRequestContext(accessToken);
			result = getUserService().deleteUser(requestContext, criteria);
		} catch (ServiceException e) {
			logger.error("Exception at UserRestService.deleteUser", e);
			throw new WebApplicationException(e);
		}

		return result;
    }
	
	/// 
	

	@GET
    @Path("/login")
    @Produces({MediaType.APPLICATION_JSON})		
	public UserDto login(@QueryParam("accessToken") String accessToken
			, @QueryParam("id") String id, @QueryParam("password") String password) 
	{
		UserDto result = null;
		try {
			RequestContext requestContext = createRequestContext(accessToken);
			UserCriteria criteria = new UserCriteria();
			criteria.setId(id);
			criteria.setPassword(password);
			result = getUserService().getUser(requestContext, criteria);
			if (result != null && password.equals(result.getPassword())) {
				result.setPassword("INVALID");
			}
					
		} catch (ServiceException e) {
			logger.error("Exception at UserRestService.login", e);
			throw new WebApplicationException(e);
		}
        return result;
    }
	
	@PUT
    @Path("/activeproject")
    @Produces({MediaType.APPLICATION_JSON})		
	public int updateActiveProject(@QueryParam("accessToken") String accessToken
			, @FormParam("userSid") long userSid, @FormParam("activeProjectSid") long activeProjectSid) 
	{
		int result = 0;
		try {
			RequestContext requestContext = createRequestContext(accessToken);
			result = getUserService().updateActiveProject(requestContext, userSid, activeProjectSid);
			
		} catch (ServiceException e) {
			logger.error("Exception at UserRestService.login", e);
			throw new WebApplicationException(e);
		}
        return result;
    }
	
	@PUT
	@Path("/{userSid}/image/{which}")
	@Override
	public int updateUserProfileImage(@QueryParam("accessToken") String accessToken, @PathParam("userSid") long userSid, @PathParam("which") String which, @FormParam("record") MediaDto media) throws RemoteException
	{
		try {
			RequestContext requestContext = createRequestContext(accessToken);
			return getUserService().updateUserProfileImage(requestContext, userSid, which, media);
		} catch (ServiceException e) {
			logger.error("Exception at UserRestService.updateUserProfileImage", e);
			throw new WebApplicationException(e);
		} 
	}	

}
